package com.yjc.drygoods.member.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.yjc.common.constant.AuthServerConstant;
import com.yjc.common.exception.BizCodeEnume;
import com.yjc.common.to.CouponAndMemberTo;
import com.yjc.common.to.CouponTo;
import com.yjc.common.utils.HttpUtils;
import com.yjc.common.utils.R;
import com.yjc.common.vo.MemberRespVo;
import com.yjc.drygoods.member.dao.MemberDao;
import com.yjc.drygoods.member.entity.MemberCollectSkuEntity;
import com.yjc.drygoods.member.entity.MemberEntity;
import com.yjc.drygoods.member.entity.MemberLevelEntity;
import com.yjc.drygoods.member.exception.*;
import com.yjc.drygoods.member.feign.CouponFeignService;
import com.yjc.drygoods.member.interceptor.LoginUserInterceptor;
import com.yjc.drygoods.member.service.MemberCollectSkuService;
import com.yjc.drygoods.member.service.MemberLevelService;
import com.yjc.drygoods.member.service.MemberService;
import com.yjc.drygoods.member.vo.MemberLoginVo;
import com.yjc.drygoods.member.vo.MemberRegistVo;
import com.yjc.drygoods.member.vo.SocialVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yjc.common.utils.PageUtils;
import com.yjc.common.utils.Query;
import org.springframework.util.StringUtils;

@Slf4j
@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {

    @Autowired
    MemberLevelService memberLevelService;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    CouponFeignService couponFeignService;

    @Autowired
    MemberCollectSkuService memberCollectSkuService;


    @Override
    public void saveCoupon(CouponTo coupon) throws Exception {
        MemberRespVo memberRespVo = LoginUserInterceptor.loginUser.get();

        //1.领取数量必须小于发行数量
        if (coupon.getReceiveCount() >= coupon.getPublishCount()) {
            throw new Exception("可领取数量不足！");
        }
        //2.必须在可领取时间内
        Date date = new Date();
        if (date.compareTo(coupon.getEnableStartTime()) == -1 || date.compareTo(coupon.getEnableEndTime()) == 1) {
            throw new Exception("不在可领取时间！");
        }
        //3.会员等级必须达标
        if (memberRespVo.getLevelId() < coupon.getMemberLevel()) {
            throw new Exception("会员等级不足！");
        }

        //4.每个人领取数量不能超过限制
        CouponAndMemberTo couponAndMemberTo = new CouponAndMemberTo();
        couponAndMemberTo.setCouponTo(coupon);
        couponAndMemberTo.setMemberRespVo(memberRespVo);

        log.info("couponAndMemberTo:{}", couponAndMemberTo);
        R r = couponFeignService.saveCouponHistory(couponAndMemberTo);
        if (r.getCode() != 0) {
//            log.info("data:{}", r.get("data"));
            throw new Exception((String) r.get("data"));
        }

    }


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<MemberEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public void registMember(MemberRegistVo memberRegistVo) {
        MemberEntity memberEntity = new MemberEntity();

        //获取会员默认等级和会员等级名称
        MemberLevelEntity memberLevel = memberLevelService.getDefaultLevel();
        memberEntity.setLevelId(memberLevel.getId());
        memberEntity.setLevelName(memberLevel.getName());

        //检查用户名和手机号是否唯一
        this.checkUserNameOnly(memberRegistVo.getUserName());
        this.checkPhoneOnly(memberRegistVo.getPhone());

        memberEntity.setUsername(memberRegistVo.getUserName());
        memberEntity.setMobile(memberRegistVo.getPhone());
        memberEntity.setNickname(memberRegistVo.getUserName());

        //设置密码
        BCryptPasswordEncoder bCrypt = new BCryptPasswordEncoder();
        String encode = bCrypt.encode(memberRegistVo.getPassword());
        memberEntity.setPassword(encode);

        //注册时间
        memberEntity.setCreateTime(new Date(System.currentTimeMillis()));
        this.save(memberEntity);
    }

    /**
     * 检查会员用户名是否唯一
     *
     * @param userName
     */
    @Override
    public void checkUserNameOnly(String userName) throws UserNameExitException {
        int count = this.count(new QueryWrapper<MemberEntity>().eq("username", userName));
        if (count > 0) {
            throw new UserNameExitException();
        }

    }

    /**
     * 检查会员手机号是否唯一
     *
     * @param phone
     */
    @Override
    public void checkPhoneOnly(String phone) throws PhoneExitException {
        int count = this.count(new QueryWrapper<MemberEntity>().eq("mobile", phone));
        if (count > 0) {
            throw new PhoneExitException();
        }
    }

    @Override
    public MemberEntity loginMember(MemberLoginVo memberLoginVo) {

        String loginAccount = memberLoginVo.getLoginAccount();
        MemberEntity memberOne = this.getOne(new QueryWrapper<MemberEntity>().eq("username", loginAccount).or().eq("mobile", loginAccount));
        if (memberOne == null) {
            return null;
        }

        String password = memberLoginVo.getPassword();
        BCryptPasswordEncoder bCry = new BCryptPasswordEncoder();
        boolean resMatch = bCry.matches(password, memberOne.getPassword());
        if (resMatch) {
            return memberOne;
        }
        return null;

    }

    @Override
    public MemberEntity weiboLogin(SocialVo socialVo) {

        MemberEntity memberEntity = this.getOne(new QueryWrapper<MemberEntity>().eq("social_id", socialVo.getUid()));
        if (memberEntity != null) {
            //存在与该社交帐号关联的本地账号
            MemberEntity memberDb = new MemberEntity();
            memberDb.setId(memberEntity.getId());
            memberDb.setAccessToken(socialVo.getAccessToken());
            memberDb.setExpiresIn(socialVo.getExpiresIn());

            this.updateById(memberDb);

            memberEntity.setAccessToken(socialVo.getAccessToken());
            memberEntity.setExpiresIn(socialVo.getExpiresIn());
            return memberEntity;

        } else {
            //需要为社交帐号注册一个本地帐号
            MemberEntity memberDb = new MemberEntity();
            //条件
            try {
                Map<String, String> circumstance = new HashMap<>();
                circumstance.put("access_token", socialVo.getAccessToken());
                circumstance.put("uid", socialVo.getUid());
                HttpResponse response = HttpUtils.doGet("https://api.weibo.com", "/2/users/show.json", "get", new HashMap<>(), circumstance);
                if (response.getStatusLine().getStatusCode() == 200) {
                    String s = EntityUtils.toString(response.getEntity());
                    JSONObject jsonObject = JSON.parseObject(s);

                    //设置用户名
                    memberDb.setUsername((String) jsonObject.get("name"));
                    //设置昵称
                    memberDb.setNickname((String) jsonObject.get("name"));

                    //设置会员等级
                    MemberLevelEntity defaultLevel = memberLevelService.getDefaultLevel();
                    memberDb.setLevelId(defaultLevel.getId());
                    memberDb.setLevelName(defaultLevel.getName());
                    log.info("会员等级信息：{}", defaultLevel);
                    log.info("会员等级：{}", defaultLevel.getName());

                    //设置头像
                    memberDb.setHeader((String) jsonObject.get("profile_image_url"));

                    //设置城市
                    memberDb.setCity((String) jsonObject.get("location"));

                    //设置性别
                    memberDb.setGender("m".equals(jsonObject.get("gender")) ? 1 : 0);

                    //设置创建时间
                    memberDb.setCreateTime(new Date());
                }
            } catch (Exception e) {
            }
            memberDb.setSocialId(socialVo.getUid());
            memberDb.setAccessToken(socialVo.getAccessToken());
            memberDb.setExpiresIn(socialVo.getExpiresIn());

            this.save(memberDb);

            return memberDb;

        }
    }

    @Override
    public MemberEntity updateMemberMySqlAndRedisById(MemberEntity member) {
        MemberRespVo memberRespVo = LoginUserInterceptor.loginUser.get();
        String codeRedis = stringRedisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + memberRespVo.getMobile());
        log.info("验证码：{}", codeRedis);
        if (!StringUtils.isEmpty(codeRedis)) {
            String code = member.getCode();
            if (codeRedis.split("_")[0].equals(code)) {
                //1.删除redis缓存的验证码
                stringRedisTemplate.delete(AuthServerConstant.SMS_CODE_CACHE_PREFIX + memberRespVo.getMobile());
                this.updateById(member);
            } else {
                throw new CodeNotRightException("验证码不正确");
            }
        } else {
            //验证码为空，手机号置空
            member.setMobile(null);
            log.info("手机号已置空：{}", member);
            this.updateById(member);
        }
        MemberEntity byId = this.getById(member.getId());
        return byId;
    }

    @Override
    public MemberRespVo clearSocial() {
        MemberRespVo memberRespVo = LoginUserInterceptor.loginUser.get();
        Long id = memberRespVo.getId();
        this.baseMapper.clearSocial(id);
        MemberEntity byId = this.getById(id);
        BeanUtils.copyProperties(byId, memberRespVo);
        return memberRespVo;
    }

    @Override
    public List<MemberEntity> getAllMemberInfo() {
        List<MemberEntity> memberInfos = this.list();
        List<MemberEntity> resList = memberInfos.stream().map(item -> {
            List<MemberCollectSkuEntity> memberCollectSkus = memberCollectSkuService.list(new QueryWrapper<MemberCollectSkuEntity>()
                    .eq("member_id", item.getId()));
            item.setMemberCollectSkuTos(memberCollectSkus);
            return item;
        }).collect(Collectors.toList());
        return resList;
    }


}